﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace LocalisationResourceManager
{
    class MainClass
    {

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            var supportedCultures = args[0].Split(',');
            string dotNetProjectsSourceRoot = args[1];
            Lrm.ResourceRepositoryPath = args[2];


            // other settings
            Lrm.WriteUniqueResourceOnly = false;
            Lrm.GenerateRes = true;
            Lrm.RebuildAccessKey = true;

            var projs = new List<String>();

            FindAvailableProjects(ref projs, new DirectoryInfo(dotNetProjectsSourceRoot));

            foreach (var s in supportedCultures)
            {
                Console.WriteLine(s);
            }

            foreach (var s in projs)
            {
                Console.WriteLine(s);
            }


            Lrm.PerformRuleEvaluation += SampleLRM_PerformRuleEvaluation;
            Lrm.GenerateResourceFileForProjects(projs.ToArray(),
                supportedCultures);
        }

        /// <summary>
        /// Gather the .NET projects in the source code hierarchy.
        /// </summary>
        /// <param name="list"></param>
        /// <param name="di"></param>
        private static void FindAvailableProjects(ref List<String> list, DirectoryInfo di)
        {
            foreach (FileInfo fi in di.GetFiles())
                if (string.Compare(Path.GetExtension(fi.Name), ".csproj", true) == 0 ||
                    string.Compare(Path.GetExtension(fi.Name), ".vbproj", true) == 0)
                    list.Add(fi.FullName);

            foreach (DirectoryInfo sdi in di.GetDirectories())
                FindAvailableProjects(ref list, sdi);
        }

        /// <summary>
        /// should not translate these properties
        /// </summary>
        private static readonly string[] ExcludedNames = new string[]{".Name",
															 ".StyleName",
															 ".Filter",
															 ".GroupFormat",
															 ".PropBag"};

        /// <summary>
        /// SQL statement pattern.
        /// </summary>
        private static readonly object[] Sqls = new object[]{new object[]{"select", "from", 1},
														new object[]{"delete", "from", 0},
														new object[]{"update", "set", 1},
														new object[]{"drop", "table", 0},
														new object[]{"create", "table", 0}};

        /// <summary>
        ///  This methond contains all the name-based and value-based rules
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void SampleLRM_PerformRuleEvaluation(object sender, PerformRuleEvaluationArgs e)
        {
            e.Handled = true;

            // Name-based rules.
            #region - Name-based rules

            // translate if ending with "_tr"
            if (e.Name.EndsWith("_tr"))
            {
                e.NeedToBeTranslated = true;
                return;
            }

            // not translate if ending with "_nt".
            if (e.Name.EndsWith("_nt"))
            {
                e.Cause = "namebased - ends with _nt";
                e.NeedToBeTranslated = false;
                return;
            }

            // some properties should not be translated.
            foreach (string end in ExcludedNames)
            {
                if (e.Name.EndsWith(end))
                {
                    e.Cause = "namebased - excluded names";
                    e.NeedToBeTranslated = false;
                    return;
                }
            }

            #endregion

            // value-based rules
            #region - Value-based rules

            // not translate if the value fits the SQL statement pattern
            foreach (object sql in Sqls)
            {
                if (e.InvariantString.ToLower().IndexOf((string)((object[])sql)[0]) == 0
                    && e.InvariantString.ToLower().IndexOf((string)((object[])sql)[1]) > ((string)((object[])sql)[0]).Length + (int)(((object[])sql)[2]))
                {
                    e.Cause = "valuebased - sql statments";
                    e.NeedToBeTranslated = false;
                    return;
                }
            }

            // not translate if there is no word.
            Regex regex = new Regex(@"[a-zA-Z]{2}");
            if (!regex.IsMatch(e.InvariantString))
            {
                e.Cause = "valuebased - no word";
                e.NeedToBeTranslated = false;
                return;
            }

            // not translate if it fits a URL pattern.
            regex = new Regex(@"://");
            Regex regex2 = new Regex(@"^[A-Z][a-z]* ");
            Regex regex3 = new Regex(@"[\.\?]$");
            if (regex.IsMatch(e.InvariantString) && ((!regex2.IsMatch(e.InvariantString) || !regex3.IsMatch(e.InvariantString))))
            {
                e.Cause = "valuebased - is url";
                e.NeedToBeTranslated = false;
                return;
            }

            // not translate if it is too long - Excel cuts it anyway.
            if (e.InvariantString.Length > Lrm.MaxLengthAnExcelCellCanHold)
            {
                e.Cause = "valuebased - text too long";
                e.NeedToBeTranslated = false;
                return;
            }

            // not translate if it is a strange word.
            if (IsStrangeString(e.InvariantString))
            {
                e.Cause = "valuebased - strange word";
                e.NeedToBeTranslated = false;
                return;
            }

            // TODO: Add more value-based rules here.

            #endregion

            e.NeedToBeTranslated = true;
        }

        /// <summary>
        /// Determines if a string is a strange one.
        /// </summary>
        /// <param name="word"></param>
        /// <returns></returns>
        private static bool IsStrangeString(string word)
        {
            System.Diagnostics.Trace.WriteLine(word);
            return false;
        }
    }
}
